#include <chronometer.h>

static void timeDelta(struct timespec* tp,struct timespec tp2, struct timespec tp1);  ///< Calcula o intervalo de tempo. \memberof chronometer_t

void chronometerStart(chronometer_t* tp){
	tp->delta.tv_sec = 0;
	tp->delta.tv_nsec = 0;
	tp->t1.tv_nsec = 0;
	tp->t1.tv_nsec = 0;
	tp->t2.tv_nsec = 0;
	tp->t2.tv_nsec = 0;
	clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&tp->t1);
}

/**
 * \memberof chronometer_t
 * \param tp O timer a ser pausado.
 */
void chronometerPause(chronometer_t* tp){
	clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&tp->t2);
	timeDelta(&tp->delta,tp->t2,tp->t1);
}

/**
 * \memberof chronometer_t
 * \param tp O timer a ser continuado.
 */
void chronometerUnpause(chronometer_t* tp){
	clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&tp->t1);
}

/**
 * \memberof chronometer_t
 * \param tp O timer a ser exibido.
 * \return Tempo em segundos.
 */
long chronometerGetSec(chronometer_t tp){
	return tp.delta.tv_sec;
}

/**
 * \memberof chronometer_t
 * \param tp O timer a ser exibido.
 * \return Tempo em nanosegundos.
 */
long chronometerGetNSec(chronometer_t tp){
	return tp.delta.tv_nsec;
}



/**
 * \memberof chronometer_t
 *
 * Calcula o período do intervalo entre "tp2" e "tp1" e o adiciona em "tp".
 *
 * \param tp Resultado final: tp += tp2 - tp1.
 * \param tp2 Tempo 2.
 * \param tp1 Tempo 1.
 */
static void timeDelta(struct timespec* tp,struct timespec tp2, struct timespec tp1){
	struct timespec temp;
	temp.tv_sec = tp2.tv_sec - tp1.tv_sec;
	if(tp2.tv_nsec >= tp1.tv_nsec)
		temp.tv_nsec = tp2.tv_nsec - tp1.tv_nsec;
	else{
		temp.tv_nsec = 1E+9 + tp2.tv_nsec - tp1.tv_nsec;
		temp.tv_sec--;
	}
	tp->tv_sec += temp.tv_sec;
	tp->tv_nsec += temp.tv_nsec;
	if(tp->tv_nsec >= 1E+9){
		tp->tv_sec++;
		tp->tv_nsec -= 1E+9;
	}
}
